package br.com.trimark.dao.generic;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import br.com.trimark.utils.exception.DataException;
import br.com.trimark.pojo.generic.IPojo;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;

public interface IGenericDAO<POJO extends IPojo<?>> extends Serializable {

	/**
	 * Retorna a classe pojo relacionada.
	 * 
	 * 
	 * @return {@link Class}
	 */
	Class<POJO> getPojoClass();

	/**
	 * Busca uma instancia do pojo passado como parametro no banco.
	 * 
	 * 
	 * @param id
	 * @return POJO
	 * @throws DataException
	 */
	POJO load(Serializable id) throws DataException;

	/**
	 * Retorna uma lista com todos os objetos do banco.
	 * 
	 * 
	 * @return {@link List}<POJO>
	 * @throws DataException
	 */
	List<POJO> findAll() throws DataException;

	/**
	 * Retorna uma lista de objetos com as mesmas caracteristicas do objeto
	 * passado como parametro.
	 * 
	 * 
	 * @param pojo
	 *            - O objeto que sera usado como modelo para a busca.
	 * @return {@link List}<POJO>
	 * @throws DataException
	 */
	List<POJO> findByExample(POJO pojo) throws DataException;

	/**
	 * Retorna uma lista de objetos de acordo com a {@link DetachedCriteria}
	 * passada como parametro.
	 * 
	 * 
	 * @param criteria
	 * @return {@link List}<POJO>
	 * @throws DataException
	 */
	List<POJO> findByCriteria(DetachedCriteria criteria) throws DataException;

	/**
	 * Retorna uma lista de objetos correspondente a consulta passada como
	 * parametro.
	 * 
	 * 
	 * @param sql
	 *            - Um objetto {@link String} com a consulta a ser realizada.
	 * @return {@link List}<POJO>
	 * @throws DataException
	 */
	List<POJO> findByQuery(String sql) throws DataException;

	/**
	 * Representa uma consulta para o contexto <b>funcao agregada MAX</b>. A
	 * Consulta para este contexto deve ser informada em <b>hql</b>.
	 * 
	 * @param hql
	 * @return o maximo id por consulta
	 * @throws DataException
	 */
	Long findMaxByQuery(String hql) throws DataException;

	/**
	 * Retorna uma lista de objetos correspondente a consulta passada como
	 * parametro. <br/>
	 * Limita o resultado em maxResult.
	 * 
	 * 
	 * @param sql
	 * @param maxResult
	 * @return {@link List}<POJO>
	 * @throws DataException
	 */
	List<POJO> findByQuery(String sql, int maxResult) throws DataException;

	/**
	 * Persiste o objeto passado como parametro.
	 * 
	 * 
	 * @param pojo
	 *            - O objeto a ser persistido.
	 * @throws DataException
	 */
	POJO save(POJO pojo) throws DataException;

	/**
	 * Persiste o novo objeto caso nao exista no banco, ou atualiza caso exista.
	 * 
	 * 
	 * @param pojo
	 *            - O objeto a ser atualizado/persistido
	 * @throws DataException
	 */
	POJO saveOrUpdate(POJO pojo) throws DataException;

	/**
	 * Atualiza o objeto passado como parametro no banco.
	 * 
	 * 
	 * @param pojo
	 *            - O objeto a ser alterado.
	 * @throws DataException
	 */
	POJO update(POJO pojo) throws DataException;

	/**
	 * Atualiza o objeto passado como parametro no banco.
	 * 
	 * 
	 * @param pojo
	 *            - O objeto a ser alterado.
	 * @throws DataException
	 */
	POJO merge(POJO pojo) throws DataException;

	/**
	 * Executa flush para a Persistencia Hibernate
	 */
	void flush();

	/**
	 * Remove o objeto passado como parametro no banco.
	 * 
	 * 
	 * @param pojo
	 *            - O objeto a ser removido.
	 * @throws DataException
	 */
	void delete(POJO pojo) throws DataException;

	/**
	 * Remove todos os objetos passados como parametro no banco.
	 * 
	 * 
	 * @param pojos
	 *            - Os objetos a serem removidos.
	 * @throws DataException
	 */
	void deleteAll(Collection<POJO> pojos) throws DataException;

	/**
	 * Cria a {@link DetachedCriteria} padrao para consultas baseadas em um
	 * objeto passado como exemplo.
	 * 
	 * 
	 * @param pojo
	 * @return {@link DetachedCriteria}
	 */
	DetachedCriteria createDetachedCriteria(POJO pojo);

	Criteria createCriteria() throws DataException;

	Session getSession() throws DataException;

	void loadAndDelete(Serializable id) throws DataException;

	List<POJO> findByQuery(String hql, String[] paramNames, Object[] values) throws DataException;

	List<POJO> findAll(String orderField) throws DataException;

	void initialize(Object value);

	List<POJO> findAll(String orderField, Boolean desc) throws DataException;

	List<POJO> find(int start, int max) throws DataException;

	Long count() throws DataException;

	List<POJO> findBySQLQuery(String queryString, Class<?> entity) throws DataException;

}